package com.brt.museum.service.auth.impl;

import static com.brt.museum.vo.Consts.PAGESIZE;
import static org.nutz.lang.Times.now;

import java.util.Collections;
import java.util.List;

import org.nutz.dao.Cnd;
import org.nutz.dao.Condition;
import org.nutz.dao.Dao;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.ContinueLoop;
import org.nutz.lang.Each;
import org.nutz.lang.ExitLoop;
import org.nutz.lang.Lang;
import org.nutz.lang.LoopException;

import com.brt.museum.bean.auth.Role;
import com.brt.museum.bean.auth.User;
import com.brt.museum.bean.auth.UserPermission;
import com.brt.museum.bean.auth.UserRole;
import com.brt.museum.dao.auth.IUserDao;
import com.brt.museum.dao.auth.IUserPermissionDao;
import com.brt.museum.dao.auth.IUserRoleDao;
import com.brt.museum.service.auth.IUserService;
import com.dgj.utils.collection.Lists;
import com.dgj.utils.db.SqlActuator;
import com.dgj.utils.entries.Result;
import com.dgj.utils.web.pager.Pager;

@IocBean
public class UserService implements IUserService {

	@Inject
	IUserDao userDao;
	@Inject
	IUserRoleDao userRoleDao;
	@Inject
	IUserPermissionDao userPermissionDao;

	@Override
	public User findByName(String userName) {
		return userDao.findByCondition(Cnd.where("name", "=", userName));
	}

	@Override
	public User addUser(User user) {
		return userDao.save(user);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.dgj.boss.service.auth.IUserService#findByRealName(java.lang.String)
	 */
	@Override
	public List<User> findByRealName(String companyName) {
		return userDao.search(Cnd.where("realName", "=", companyName));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.dgj.boss.service.auth.IUserService#findById(int)
	 */
	@Override
	public User findById(int id) {
		return userDao.findById(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.dgj.boss.service.auth.IUserService#update(com.dgj.model.bean.auth
	 * .User, java.lang.String[])
	 */
	@Override
	public Result update(User user, String... updateField) {
		return userDao.update(user, updateField) ? Result.success() : Result.fail("更新用户失败");
	}

	@Override
	public Pager<User> listByPage(int page) {
		Pager<User> pager = new Pager<User>(PAGESIZE, page);
		pager.setEntities(userDao.searchByPage(null, page, PAGESIZE));
		pager.setCount(userDao.countAll());
		return pager;
	}

	@Override
	public Pager<User> searchByKey(int page, String key) {
		String searchKey = String.format("%%%s%%", key);
		Condition cnd = Cnd.where("name", "like", searchKey).or("realName", "like", searchKey);
		Pager<User> pager = new Pager<User>(PAGESIZE, page);
		pager.setEntities(userDao.searchByPage(cnd, page, PAGESIZE));
		pager.setCount(userDao.countByCnd(cnd));
		return pager;
	}

	@Override
	public boolean deleteUser(int id) {
		return userDao.delById(id);
	}

	@Override
	public List<Record> findUserRoleStatusByUserId(int id) {
		Dao dao = userDao.getDao();
		Sql sql = dao.sqls().create("find.user.role.status.by.user.id");
		sql.params().set("id", id);
		return SqlActuator.runReport(sql, dao);
	}

	@Override
	public Result setRole(int[] ids, int userId) {
		/**
		 * 1.查询用户现在的全部角色<br>
		 * 2.遍历角色,如果存在更新时间,如果不存在删除,处理之后从目标数组中移除元素<br>
		 * 3.遍历剩余的目标数组,添加关系
		 */
		if (ids == null) {
			ids = new int[] {};
		}
		List<Integer> newIds = Lang.array2list(ids, Integer.class);
		Collections.sort(newIds);
		List<UserRole> userRoles = userRoleDao.search(Cnd.where("userId", "=", userId));
		for (UserRole role : userRoles) {
			int i = 0;
			if ((i = Collections.binarySearch(newIds, role.getRoleId())) >= 0) {
				newIds.remove(i);
				role.setPowerTime(now());
				userRoleDao.update(role);
			} else {
				userRoleDao.delById(role.getId());
			}
		}
		for (int rid : newIds) {
			UserRole relation = new UserRole();
			relation.setRoleId(rid);
			relation.setUserId(userId);
			userRoleDao.save(relation);
		}
		return Result.success();
	}

	@Override
	public List<Record> findUserPermissionByUserId(int id) {
		final Dao dao = userDao.getDao();
		Sql sql = dao.sqls().create("find.uer.permission.by.user.id");
		sql.params().set("id", id);
		return SqlActuator.runReport(sql, dao);
	}

	@Override
	public Result setPermission(int[] ids, int userId) {
		/**
		 * 1.查询用户现在的全部权限<br>
		 * 2.遍历权限,如果存在更新时间,如果不存在删除,处理之后从目标数组中移除元素<br>
		 * 3.遍历剩余的目标数组,添加关系
		 */
		if (ids == null) {
			ids = new int[] {};
		}
		List<Integer> newIds = Lang.array2list(ids, Integer.class);
		Collections.sort(newIds);
		List<UserPermission> list = userPermissionDao.search(Cnd.where("userId", "=", userId));
		for (UserPermission user : list) {
			int i = 0;
			if ((i = Collections.binarySearch(newIds, user.getPermissionId())) >= 0) {
				newIds.remove(i);
				user.setPowerTime(now());
				userPermissionDao.update(user);
			} else {
				userPermissionDao.delById(user.getId());
			}
		}
		for (int pid : newIds) {
			UserPermission userp = new UserPermission();
			userp.setUserId(userId);
			userp.setPermissionId(pid);
			userPermissionDao.save(userp);
		}
		return Result.success();
	}

	@Override
	public List<User> findUserByRole(Role role) {
		Dao dao = userDao.getDao();
		Sql sql = dao.sqls().create("find.users.by.role.name");
		sql.params().set("name", role.getName());
		List<Record> records = SqlActuator.runReport(sql, dao);
		final List<User> users = Lists.newArrayList();
		Lang.each(records, new Each<Record>() {

			@Override
			public void invoke(int index, Record record, int length) throws ExitLoop, ContinueLoop, LoopException {
				users.add(record.toEntity(userDao.getDao().getEntity(User.class)));
			}
		});
		return users;
	}

}
